package tr.edu.metu.is.mega.server.business;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import tr.edu.metu.is.mega.common.dto.ActivityDTO;
import tr.edu.metu.is.mega.common.dto.ActivityType;
import tr.edu.metu.is.mega.common.dto.CourseAssistantDTO;
import tr.edu.metu.is.mega.common.dto.CourseDTO;
import tr.edu.metu.is.mega.common.dto.CourseStudentDTO;
import tr.edu.metu.is.mega.common.dto.TeamDTO;
import tr.edu.metu.is.mega.server.core.AbstractDTOHelper;
import tr.edu.metu.is.mega.server.dao.UserDAO;
import tr.edu.metu.is.mega.server.entity.Activity;
import tr.edu.metu.is.mega.server.entity.Course;
import tr.edu.metu.is.mega.server.entity.Courseassistant;
import tr.edu.metu.is.mega.server.entity.Coursestudent;
import tr.edu.metu.is.mega.server.entity.Team;
import tr.edu.metu.is.mega.server.entity.Teammember;

/**
 * Helper class to convert between DTO and entity.
 */
public class CourseDTOHelper extends AbstractDTOHelper<CourseDTO, Course> {

    private final UserDTOHelper userDTOHelper;

    private final UserDAO userDAO = new UserDAO();

    /**
     * Default constructor.
     */
    public CourseDTOHelper() {
        userDTOHelper = new UserDTOHelper();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public CourseDTO convertToDTO(Course from) {
        CourseDTO to = new CourseDTO();
        to.setPkid(from.getPkid());
        to.setCode(from.getCode());
        to.setName(from.getName());
        to.setSemester(from.getSemester());
        if (from.getInstructor() != null) {
            to.setInstructor(userDTOHelper.convertToDTO(from.getInstructor()));
        }
        if (from.getCourseassistants() != null) {
            List<CourseAssistantDTO> courseAssistants = new ArrayList<CourseAssistantDTO>(from.getCourseassistants().size());
            for (Courseassistant courseassistant : from.getCourseassistants()) {
                CourseAssistantDTO courseAssistantDTO = new CourseAssistantDTO();
                courseAssistantDTO.setPkid(courseassistant.getPkid());
                courseAssistantDTO.setCourse(to);
                courseAssistantDTO.setUser(userDTOHelper.convertToDTO(courseassistant.getSystemuser()));
                courseAssistants.add(courseAssistantDTO);
            }
            to.setAssistants(courseAssistants);
        }
        if (from.getCoursestudents() != null) {
            List<CourseStudentDTO> studentDTOs = new ArrayList<CourseStudentDTO>(from.getCoursestudents().size());
            for (Coursestudent coursestudent : from.getCoursestudents()) {
                CourseStudentDTO dto = new CourseStudentDTO();
                dto.setPkid(coursestudent.getPkid());
                dto.setCourse(to);
                dto.setUser(userDTOHelper.convertToDTO(coursestudent.getSystemuser()));
                studentDTOs.add(dto);
            }
            to.setStudents(studentDTOs);
        }
        if (from.getTeams() != null) {
            List<TeamDTO> teamDTOs = new ArrayList<TeamDTO>(from.getTeams().size());
            for (Team team : from.getTeams()) {
                TeamDTO dto = new TeamDTO();
                dto.setPkid(team.getPkid());
                dto.setCourse(to);
                dto.setLogo(team.getLogo());
                dto.setTeamName(team.getTeamname());
                List<Teammember> teammembers = team.getTeammembers();
                List<CourseStudentDTO> users = new ArrayList<CourseStudentDTO>(teammembers.size());
                for (Teammember teammember : teammembers) {
                    CourseStudentDTO studentDTO = new CourseStudentDTO();
                    studentDTO.setPkid(teammember.getCoursestudent().getPkid());
                    studentDTO.setUser(userDTOHelper.convertToDTO(teammember.getCoursestudent().getSystemuser()));
                    studentDTO.setCourse(to);
                    users.add(studentDTO);
                }
                dto.setMembers(users);
                teamDTOs.add(dto);
            }
            to.setTeams(teamDTOs);
        }

        if (from.getActivities() != null) {
            List<ActivityDTO> activityDTOs = new ArrayList<ActivityDTO>(from.getActivities().size());
            for (Activity activity : from.getActivities()) {
                ActivityDTO dto = new ActivityDTO();
                dto.setPkid(activity.getPkid());
                dto.setDescription(activity.getDescription());
                dto.setDueDate(activity.getDuedate());
                dto.setAlertTime(activity.getAlerttime());
                dto.setType(ActivityType.findByCode(activity.getSubmissiontype()));
                activityDTOs.add(dto);
            }
            to.setActivities(activityDTOs);
        }

        return to;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void convertToEntity(CourseDTO from, Course to) {
        to.setPkid(from.getPkid());
        to.setCode(from.getCode());
        to.setName(from.getName());
        to.setSemester(from.getSemester());
        if (from.getInstructor() != null) {
            to.setInstructor(userDAO.findById(from.getInstructor().getPkid()));
        }
        if (from.getAssistants() != null) {
            List<Courseassistant> courseassistants = new ArrayList<Courseassistant>(from.getAssistants().size());
            for (CourseAssistantDTO assistantDTO : from.getAssistants()) {
                Courseassistant courseassistant = new Courseassistant();
                courseassistant.setPkid(assistantDTO.getPkid());
                courseassistant.setCourse(to);
                courseassistant.setSystemuser(userDAO.findById(assistantDTO.getUser().getPkid()));
                courseassistants.add(courseassistant);
            }
            to.setCourseassistants(courseassistants);
        }
        if (from.getStudents() != null) {
            List<Coursestudent> studentEntities = new ArrayList<Coursestudent>(from.getStudents().size());
            for (CourseStudentDTO dto : from.getStudents()) {
                Coursestudent entitiy = new Coursestudent();
                entitiy.setPkid(dto.getPkid());
                entitiy.setCourse(to);
                entitiy.setSystemuser(userDAO.findById(dto.getUser().getPkid()));
                studentEntities.add(entitiy);
            }
            to.setCoursestudents(studentEntities);
        }
        if (from.getTeams() != null) {
            List<Team> teams = new ArrayList<Team>(from.getTeams().size());
            for (TeamDTO teamDTO : from.getTeams()) {
                Team team = new Team();
                team.setPkid(teamDTO.getPkid());
                team.setCourse(to);
                team.setLogo(teamDTO.getLogo());
                team.setTeamname(teamDTO.getTeamName());
                List<CourseStudentDTO> students = teamDTO.getMembers();
                List<Teammember> teamMembers = new ArrayList<Teammember>(students.size());
                for (CourseStudentDTO courseStudentDTO : students) {
                    Teammember teammember = new Teammember();
                    Coursestudent coursestudent = new Coursestudent();
                    coursestudent.setPkid(courseStudentDTO.getPkid());
                    coursestudent.setCourse(to);
                    coursestudent.setSystemuser(userDAO.findById(courseStudentDTO.getUser().getPkid()));
                    teammember.setCoursestudent(coursestudent);
                    teammember.setTeam(team);
                    teamMembers.add(teammember);
                }
                team.setTeammembers(teamMembers);
                teams.add(team);
            }
            to.setTeams(teams);
        }
        if (from.getActivities() != null) {
            List<Activity> activitys = new ArrayList<Activity>(from.getActivities().size());
            for (ActivityDTO dto : from.getActivities()) {
                Activity entity = new Activity();
                entity.setPkid(dto.getPkid());
                entity.setCourse(to);
                entity.setDescription(dto.getDescription());
                entity.setDuedate(new Timestamp(dto.getDueDate().getTime()));
                if (dto.getAlertTime() != null) {
                    entity.setAlerttime(new Timestamp(dto.getAlertTime().getTime()));
                }
                entity.setSubmissiontype(dto.getType().getCode());
                activitys.add(entity);
            }
            to.setActivities(activitys);
        }
    }
}
